package intranet.server;
import intranet.client.ProfileService;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;


import com.google.gwt.user.server.rpc.RemoteServiceServlet;

@SuppressWarnings("serial")
public class ProfileServiceImpl extends RemoteServiceServlet implements
		ProfileService {

	String DB, User, Password;
	Connection connect = null;
	//Info connexion
	String url = "jdbc:postgresql:";
    String db = "intranet-grpc";
    String driver = "org.postgresql.Driver";
    String user = "postgres";
    String pass = "grpc";

    HashMap<String, String[]> teacherMap=null;
    /**
     * la conexion à la base de donnée
     * @return true si connecté
     * @return false sinon
     */
	public boolean connect() {
		
		try {
		    Class.forName("org.postgresql.Driver");
	 
		  } catch (ClassNotFoundException e) {
		    System.out.println("Can't find the JDBC driver in your path!");
		    e.printStackTrace();
		    return false;
		  }
	 
		  System.out.println("PostgreSQL JDBC driver loaded!");
	
	 
		  try {
	 
			  connect = DriverManager.getConnection("jdbc:postgresql:intranet-grpc","postgres", "grpc");
	 
		  } catch (SQLException e) {
		    System.out.println("Connection Failed!");
		    e.printStackTrace();
		    return false;
		  }
		  return true;
	}
	
	/**
	 * la fonction déconecter pour le service de la base de donnée
	 * @return true si c'est réussi
	 * @return false sinon
	 */
	public boolean disconnect()
	  {
	      try{
	          connect.close();
	       return true;
	          } catch (Exception e){}
	          return false;
	  }
	
	
	
	/**
	 * fonction de selection d'informations à partir d'une base de donnée
	 * @param requête sql
	 * @return HashMap resultat de requête
	 */
	public HashMap<String, String[]> select(String Requete) 
	{
		HashMap<String, String[]> superArray=null;
		//Essai de connection
		if (connect())
		{
			ResultSetMetaData data=null;
			Statement state = null;
			ResultSet result = null;
			
			//Essai d'execution de la requete
			try {
				state = connect.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
				result = state.executeQuery(Requete);
				data = result.getMetaData();
				superArray = new HashMap<String, String[]>();
				
				String[] s;
			
				//Recuperation des résultats
				for (int i = 1; i <= data.getColumnCount(); i++) 
				{			
					//Methode pour recuperer le nombre de tuples retournés
					result.last();
					s= new String[result.getRow()];
					System.out.println("TailleV : "+result.getRow());
					int rang =0;
					result.beforeFirst();
					
					//Pour chaque tuple
					while (result.next())
					{
						s[rang]=result.getString(i);
						rang++;
					}
					superArray.put(data.getColumnName(i),s);
				}
					
			} catch (Exception e) 
			{
				e.printStackTrace();
			}
			disconnect();
			return superArray;
		}
		else
		{
			disconnect();
			return superArray;
		}
	}

	 /**
		 * la fonction update pour la mise à jour des données
		 * @param requête sql
		 * @return >0 si c'est réussi
		 * @return <0 sinon
		 */
	 public int update(String requete)
	 {

		 Statement state=null; 
		 int x=-1;
		 if (connect())
		 {
			 x=-2;
		 try{
			 state=connect.createStatement();
			 x=state.executeUpdate(requete);
		 }
		 catch (Exception e){}
		 disconnect();
		 }
		 return x;
	 }

	 
/**
 * fonction de cryptage 
 * @param password
 * @param grainofsalt
 * @return String valeur
 */
	 	 
	 String getMd5Digest(String ps,String gr)
	    {

	      try
	        {
	    		MessageDigest m= MessageDigest.getInstance("MD5");
				m.reset();
				
				m.update((ps+gr).getBytes());
				byte[] digest = m.digest();
				BigInteger bigInt = new BigInteger(1, digest);
				String encryptedPassword = bigInt.toString(16);

				while (encryptedPassword.length() < 32) {
					encryptedPassword = "0" + encryptedPassword;
				}
				
				return encryptedPassword;
	           
	        }
	        catch(NoSuchAlgorithmException e)
	        {
	            throw new RuntimeException(e);
	        }
	    }
	 

	 /**
	 * mise à jour des données et cryptage du password
	 * @param login,name,first name,phone,email
	 * @return integer valeur 
	 */

	 
	 public int updat(String log,String nm,String fr,String tel,String em,String pass) 
	 {  
		 
		 String z=null;
		 String encpass=null;
			String reqTeacher ="select teacher_grainofsalt,teacher_password from teacher where teacher_login="+"'"+log+"'";
			teacherMap=select(reqTeacher);
			z=teacherMap.get("teacher_grainofsalt")[0].toString();
			encpass=teacherMap.get("teacher_password")[0].toString();
  	
    	String cryptpass = getMd5Digest(pass,z);

			String  strreq1="update teacher SET " +
			 	"teacher_name="+"'"+nm+"'"+","+
				"teacher_firstname="+"'"+fr+"'"+","+
				"teacher_tel="+"'"+tel+"'"+","+
				"teacher_email="+"'"+em+"'"+","+
				"teacher_password="+"'"+cryptpass+"'"+
				" where teacher.teacher_login="+"'"+log+"'"+" and "+" teacher.teacher_password="+"'"+encpass+"'"; 

			
		
			 Statement state=null; 
			 int x=-1;
			 if (connect())
			 {
				 x=-2;
			 try{
				 state=connect.createStatement();
				 x=state.executeUpdate(strreq1);
			 }
			 catch (Exception e){}
			 disconnect();
			 }
			 return x;
	
	 }


	
	

}
